package com.intel.utils 
{
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.system.System;
	import flash.utils.Timer;
	import pcb.models.vo.Slide;
	import pcb.views.library.NamingConvention;
	import pcb.views.uievents.LabelEvent;
	import pcb.views.uievents.SlideEvent;
	
	/**
	 * ...
	 * @author Fintan Boyle
	 */
	public class TransitionManager 
	{
		
		private var playClip:Boolean;
		private var container:MovieClip;
		private var inFrameLabel:String;
		private var containerFrameLabel:String;
		private var slide:MovieClip;
		
		public function TransitionManager(){}
		
		
		public function changeFrame(container:MovieClip, containerFrameLabel:String, inFrameLabel:String, outFrameLabel:String, playClip:Boolean, transitionTime:Number=0):void 
		{
			this.containerFrameLabel = containerFrameLabel;
			this.playClip = playClip;
			this.container = container;
			this.inFrameLabel = inFrameLabel;
				
			//container.gotoAndStop(containerFrameLabel) is not guaranteed to work first time round
			
			//the contents of the current frame is not immediately accessible and the latency can vary
			//calling invalidate() will redraw the frame and ensure that the frame contents are accessible in
			//container_onRendered
			container.stage.addEventListener(Event.RENDER, container_onRendered);
			container.stage.invalidate();
			
		}
		
		private function container_onRendered(e:Event):void 
		{
			//Debugger.traceOut("container_onRendered");
			
			//now we can safely call gotoAndStop
			if (containerFrameLabel != "mainTimeline") container.gotoAndStop(containerFrameLabel);
			
			//Debugger.traceOut("container.mcLessonPart " + container.mcLessonPart + "   containerFrameLabel: "+ container.currentLabel);
				
			container.addEventListener(Event.FRAME_CONSTRUCTED, container_onFrameConstructed);
			
			e.target.removeEventListener(Event.RENDER, container_onRendered);
		}
		
		private function deferredPlaySlideAnimation():void 
		{
			//Debugger.traceOut("playclip ? "+ playClip);
				
			//Debugger.traceOut("container.mcLessonPart " + container.mcLessonPart);
			//Debugger.traceOut("current frame: "+ this.container.currentFrame + "  label: "+ this.container.currentLabel);
			//Debugger.traceOut("number of children in container: "+ this.container.numChildren );
			//Debugger.traceOut("getChildAt(0) in container: "+ this.container.getChildAt(0) );
			
			if (this.container.mcLessonPart != null) {
				container.mcLessonPart.addEventListener(Event.FRAME_CONSTRUCTED, slideReady);
				container.mcLessonPart.gotoAndStop(inFrameLabel);
				
				//free for garbage collection
				container = null;
				Debugger.traceOut("ready to play");
			
			}else{
				container.addEventListener(Event.FRAME_CONSTRUCTED, container_onFrameConstructed);
				//thius was throwing an error
				//container.gotoAndStop(container.nextFrame);
				Debugger.traceOut("-- Learn frame not constructed yet!")
			}
			
		}
		
		private function container_onFrameConstructed(e:Event):void 
		{
			e.target.removeEventListener(Event.FRAME_CONSTRUCTED, container_onFrameConstructed);
			
			this.container = e.target as MovieClip;
			container.gotoAndStop(containerFrameLabel);
		
			if(this.container){ //frame 1 is not labelled
				deferredPlaySlideAnimation();
			}else {
				Debugger.traceOut("Learn frame not constructed yet!")
			}
		}
		
		public function nextFrame(container:MovieClip):void {
			container.nextFrame();
		}
		
		private function slideReady(e:Event):void 
		{
			e.target.removeEventListener(Event.FRAME_CONSTRUCTED, slideReady);
			if (playClip) playSlideAnimation(e.target as MovieClip, NamingConvention.SLIDE_PREFIX + e.target.currentLabel);
		}
		
		private function playSlideAnimation(lessonMC:MovieClip, label:String):void 
		{
			slide = lessonMC.getChildByName(label) as MovieClip;
			
			Debugger.traceOut(">>slideReady - "+ slide);
			
			if (slide != null) { 
				slide.addEventListener(Event.ENTER_FRAME, silde_onEnterFrame);
				slide.addEventListener(Event.REMOVED_FROM_STAGE, slide_onRemoved);
				slide.gotoAndPlay(2);
			}else {
				Debugger.traceOut("the slide was null");
			}
			
			slide = null;
		}
		
		private function slide_onRemoved(e:Event):void 
		{
			var mc:MovieClip = e.target as MovieClip;
			mc.stop();
			if (mc.hasEventListener(Event.ENTER_FRAME)) {				
				mc.removeEventListener(Event.ENTER_FRAME, silde_onEnterFrame);
			}
			mc.removeEventListener(Event.REMOVED_FROM_STAGE, slide_onRemoved);
			
			//mc.parent.removeChild(mc);
			
			mc = null;
			
		}
		
		private function silde_onEnterFrame(e:Event):void 
		{
			var mc:MovieClip = e.target as MovieClip;
			if (mc.currentFrame == mc.totalFrames) {
				mc.dispatchEvent(new Event(SlideEvent.ANIMATION_ENDED, true));
				mc.removeEventListener(Event.ENTER_FRAME, silde_onEnterFrame);
			}
			mc = null;
		}
		
		public function pauseCurrentFrame(container:MovieClip, containerFrameLabel:String):void 
		{
			if(containerFrameLabel != "mainTimeline") container.gotoAndStop(containerFrameLabel);
			container.mcLessonPart.addEventListener(Event.FRAME_CONSTRUCTED, pauseFrame_onSlideReady);
		}
		
		private function pauseFrame_onSlideReady(e:Event):void 
		{			
			var slide:MovieClip = e.target.getChildByName(NamingConvention.SLIDE_PREFIX + e.target.currentLabel) as MovieClip;
			if (slide != null) slide.stop();
			
			e.target.removeEventListener(Event.FRAME_CONSTRUCTED, pauseFrame_onSlideReady);
		}
		
		public function dispose():void {
			
			
			if (this.container){
				if (this.container.hasEventListener(Event.FRAME_CONSTRUCTED)) {
					this.container.removeEventListener(Event.FRAME_CONSTRUCTED, container_onFrameConstructed);
				}
				if (this.container.stage.hasEventListener(Event.RENDER)) {
					this.container.removeEventListener(Event.RENDER, container_onRendered);
				}
				if (this.container.mcLessonPart != null) {
					if (container.mcLessonPart.hasEventListener(Event.FRAME_CONSTRUCTED)) {
						container.mcLessonPart.removeEventListener(Event.FRAME_CONSTRUCTED, slideReady);
						//container.mcLessonPart.removeEventListener(Event.FRAME_CONSTRUCTED, pauseFrame_onSlideReady);
					}
					
				}
			}
			if (this.slide) {
				if (slide.hasEventListener(Event.ENTER_FRAME) ){
					slide.removeEventListener(Event.ENTER_FRAME, silde_onEnterFrame);
				}
				if (slide.hasEventListener(Event.REMOVED_FROM_STAGE) ){
					slide.removeEventListener(Event.REMOVED_FROM_STAGE, slide_onRemoved);
				}
			}
			
			this.slide = null;
			this.containerFrameLabel = null;
			this.playClip = false;
			this.container = null;
			this.inFrameLabel = null;
			
		}		
	}
	
}